package parts 
{
	import events.PartEvent;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.utils.Dictionary;
	import gs.TweenLite;
	import model.ApplicationModel;
	import model.ApplicationView;
	import util.site.PartCodes;
	
	/**
	 * 
	 * @author Kasoi
	 */
	public class PartManager extends Sprite 
	{
		
		static private const MIN_SWITCH_TIME: Number = 1200;
		
		////////////////////////////////////////////////////////////////////
		// Public properties
		////////////////////////////////////////////////////////////////////
		
		public function get currentPartCode() : String 
		{
			return this._currentPartCode;
		}
		
		public function get currentPart() : PartBase 
		{
			return this._currentPart;
		}
		
		////////////////////////////////////////////////////////////////////
		// Private properties
		////////////////////////////////////////////////////////////////////
		
		private var codes: Array;
		
		private var partClasses: Array;
		
		private var container: Sprite;
		
		private var _currentPart: PartBase;
		
		private var hidingPart: PartBase;
		
		private var _currentPartCode: String;
		
		private var lastSwitchTime: Number = 0;
		
		private var loadingStarted: Boolean = false;
		
		////////////////////////////////////////////////////////////////////
		// Public methods
		////////////////////////////////////////////////////////////////////
		
		public function PartManager(firstPart: String, part: Class) 
		{
			this.name = 'PartManager';
			this.codes = [];
			this.partClasses = [];
			
			this.container = new Sprite();
			
			this.addChild(this.container);
			
			this.addPart(firstPart, part);
			this.openPart(firstPart);
		}
		
		public function addPart(code: String, part: Class) : void 
		{
			this.codes.push(code);
			this.partClasses.push(part);
		}
		
		public function changePart(code: String) : void 
		{
			//ApplicationView.getInstance().hideItems(0.5);
			if (this._currentPart != null)
			{
				this.switchParts(this._currentPart, code);
			}
			else this.openPart(code);
		}

		
		////////////////////////////////////////////////////////////////////
		// Private methods
		////////////////////////////////////////////////////////////////////
		
		private function switchParts(part: PartBase, newPartCode: String) : void 
		{
			if (this.hidingPart != null)
			{
				var state: String = this.hidingPart.partState;
				//trace('PartManager.switchParts :', state);
					if (state != PartBase.DESTROYED && state != state != PartBase.CLOSED)
					{
						this.hidingPart.removeEventListener(PartEvent.PART_CLOSED, this.part_onClose);
						this.hidingPart.destroy();
						this.part_onClose(null);
					}
			}
			this.hidingPart = this._currentPart;
			this._currentPartCode = newPartCode;
			
			this.dispatchEvent(new PartEvent(PartEvent.PART_CHANGED));
			
			this.hidingPart.close();
			this.hidingPart.mouseEnabled = this.hidingPart.mouseChildren = false;
		}
		
		private function openPart(code: String) : void 
		{	
			while (this.numChildren > 0) this.removeChildAt(0);
			
			if (code == PartCodes.LOADER) this.loadingStarted = true;
			
			for (var i: int = 0; i < this.codes.length; i++) 
			{
				if (this.codes[i] == code) 
				{
					var c: Class = this.partClasses[i];
					var part: PartBase = (new c()) as PartBase;
					this.addChild(part);
					part.addEventListener(PartEvent.PART_CLOSED, this.part_onClose);
					this._currentPart = part;
					part.open();
					part.addEventListener(PartEvent.PART_OPENED, this.part_onOpen);
				}
			}
		}
		
		////////////////////////////////////////////////////////////////////
		// Listeners
		////////////////////////////////////////////////////////////////////
		
		private function part_onClose(e: PartEvent) : void 
		{
			if (this.hidingPart != null && this.contains(this.hidingPart)) 
			{
				this.removeChild(this.hidingPart);
			}
			this.hidingPart = null;
			Log.fatal('PartManager.part_onClose : Opening ' + this._currentPartCode + ' pat now');
			
			this.openPart(this._currentPartCode);
		}
		
		private function part_onOpen(e: PartEvent) : void 
		{
			this.dispatchEvent(new Event(Event.OPEN));
		}
	}
	
}